import {
  IsOptional,
  IsNumber,
  IsString,
  IsEnum,
  Min,
  Max,
  MaxLength
} from 'class-validator';
import { ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';

/**
 * 公开文章查询 DTO
 * 用于验证和规范化查询参数
 */
export class PublicQueryDto {
  @ApiPropertyOptional({
    description: '页码',
    example: 1,
    minimum: 1,
    default: 1
  })
  @IsOptional()
  @Type(() => Number)
  @IsNumber({}, { message: '页码必须是数字' })
  @Min(1, { message: '页码不能小于1' })
  page?: number = 1;

  @ApiPropertyOptional({
    description: '每页数量',
    example: 10,
    minimum: 1,
    maximum: 50,
    default: 10
  })
  @IsOptional()
  @Type(() => Number)
  @IsNumber({}, { message: '每页数量必须是数字' })
  @Min(1, { message: '每页数量不能小于1' })
  @Max(50, { message: '每页数量不能超过50' })
  limit?: number = 10;

  @ApiPropertyOptional({
    description: '搜索关键词（标题、内容、摘要）',
    example: 'NestJS',
    maxLength: 100
  })
  @IsOptional()
  @IsString({ message: '搜索关键词必须是字符串' })
  @MaxLength(100, { message: '搜索关键词长度不能超过100个字符' })
  search?: string;

  @ApiPropertyOptional({
    description: '标签名称',
    example: 'JavaScript',
    maxLength: 50
  })
  @IsOptional()
  @IsString({ message: '标签必须是字符串' })
  @MaxLength(50, { message: '标签长度不能超过50个字符' })
  tag?: string;

  @ApiPropertyOptional({
    description: '分类ID',
    example: 1,
    minimum: 1
  })
  @IsOptional()
  @Type(() => Number)
  @IsNumber({}, { message: '分类ID必须是数字' })
  @Min(1, { message: '分类ID不能小于1' })
  categoryId?: number;

  @ApiPropertyOptional({
    description: '分类名称',
    example: '技术',
    enum: ['技术', '生活', '随笔', '教程']
  })
  @IsOptional()
  @IsEnum(['技术', '生活', '随笔', '教程'], { 
    message: '分类必须是：技术、生活、随笔、教程 中的一个' 
  })
  category?: '技术' | '生活' | '随笔' | '教程';

  @ApiPropertyOptional({
    description: '排序字段',
    example: 'publishedAt',
    enum: ['publishedAt', 'createdAt', 'viewCount', 'likeCount', 'title']
  })
  @IsOptional()
  @IsEnum(['publishedAt', 'createdAt', 'viewCount', 'likeCount', 'title'], {
    message: '排序字段必须是：publishedAt、createdAt、viewCount、likeCount、title 中的一个'
  })
  sortBy?: 'publishedAt' | 'createdAt' | 'viewCount' | 'likeCount' | 'title' = 'publishedAt';

  @ApiPropertyOptional({
    description: '排序方向',
    example: 'DESC',
    enum: ['ASC', 'DESC'],
    default: 'DESC'
  })
  @IsOptional()
  @IsEnum(['ASC', 'DESC'], {
    message: '排序方向必须是：ASC 或 DESC'
  })
  sortOrder?: 'ASC' | 'DESC' = 'DESC';
}

/**
 * 分页响应 DTO
 */
export class PaginationDto {
  @ApiPropertyOptional({
    description: '当前页码',
    example: 1
  })
  page: number;

  @ApiPropertyOptional({
    description: '每页数量',
    example: 10
  })
  limit: number;

  @ApiPropertyOptional({
    description: '总记录数',
    example: 100
  })
  total: number;

  @ApiPropertyOptional({
    description: '总页数',
    example: 10
  })
  totalPages: number;

  @ApiPropertyOptional({
    description: '是否有上一页',
    example: false
  })
  hasPrevious: boolean;

  @ApiPropertyOptional({
    description: '是否有下一页',
    example: true
  })
  hasNext: boolean;
}

/**
 * 公开文章列表响应 DTO
 */
export class PublicPostsResponseDto {
  @ApiPropertyOptional({
    description: '文章列表',
    type: 'array'
  })
  posts: any[];

  @ApiPropertyOptional({
    description: '分页信息',
    type: PaginationDto
  })
  pagination: PaginationDto;
}
